import requests
import hashlib
import time
import json
from app.core.config import settings
import logging


class ApiClient:
    def __init__(self):
        """
        初始化 API 客户端
        """
        self.base_url =  settings.YOUSHU_API_URL
        self.gskey = settings.YOUSHU_API_KEY

    def _generate_jssign(self, params):
        # 过滤空值
        filtered = {k: v for k, v in params.items() if v is not None and v != ""}
        # 按照 key 的字典序排序
        sorted_keys = sorted(filtered.keys())
        # print('sorted_keys：',sorted_keys)
        # 拼接 key1=val1&key2=val2...
        param_str = "&".join(f"{key}={filtered[key]}" for key in sorted_keys)
        # print("param_str:",param_str)
        # 拼接 &gskey
        param_str_with_gskey = f"{param_str}&gskey={self.gskey}"
        print("param_str_with_gskey:",param_str_with_gskey)
        # MD5 加密
        md5_val = hashlib.md5(param_str_with_gskey.encode('utf-8')).hexdigest()
        # print("md5_val:",md5_val)
        return md5_val
    
    def build_status(self, task_id, status, remake):
        endpoint = "/api/buildStatus"
        url = self.base_url + endpoint
        params = {
            "taskId": task_id,
            "status": status,
            "remake": remake
        }
        jssign = self._generate_jssign(params)
        headers = {
            "Content-Type": "application/json;charset=UTF-8",
            "gssign": jssign
        }

        response = requests.post(url, headers=headers, json=params)
        print("回调接口")
        logging.info(f"回调接口")
        print("response:",response)
        logging.info(f"response={response}")
        print("response.json:",response.json())
        logging.info(f"response.json={response.json}")
        return response.json()

    def get_current_user_information(self, project, token):
        # 调用 verify_md5 验证 token
        verify, uid = self.verify_md5(token)
        print("verify_md5返回结果: verify =", verify, ", uid =", uid)
        logging.info(f"Token验证结果: verify={verify}, uid={uid}")
        
        # 如果验证失败，直接返回错误信息
        if not verify:
            print("Token验证失败，直接返回错误")
            logging.error(f"Token验证失败: token={token}")
            return {"code": 400, "msg": "Token验证失败"}

        # token 验证成功，继续请求用户信息
        endpoint = "/api/currentUserInformation"
        url = self.base_url + endpoint
        params = {
            "uid": uid,  # 将 verify_md5 方法返回的 uid 放入请求参数
            "project": project
        }
        jssign = self._generate_jssign(params)
        headers = {
            "Content-Type": "application/json;charset=UTF-8",
            "gssign": jssign
        }

        # 打印请求数据、请求头和请求 URL
        print("请求数据:", params)
        logging.info(f"请求数据={params}")
        print("请求头:", headers)
        logging.info(f"请求头={headers}")
        print("请求 URL:", url)
        logging.info(f"请求 URL={url}")

        try:
            # 发起 POST 请求到 API
            response = requests.post(url, headers=headers, json=params)
            response_data = response.json()
            logging.info(f"response_data={response_data}")
            print("response_data:", response_data)

            # 根据响应数据处理返回值
            status = response_data.get("status")
            # 根据 status 返回值，做统一格式封装
            if status == 200 and response_data.get("success"):
                # 返回成功
                task_id = response_data["data"].get("taskId")
                return {
                    "code": 200,
                    "msg": "成功",
                    "taskId": task_id,
                    "jssign": jssign
                }
            elif status == 400:
                # 业务错误
                return {
                    "code": 400,
                    "msg": "业务错误"
                }
            elif status == 401:
                # 用户不存在
                logging.warning(f"用户不存在: uid={uid}, project={project}")
                return {
                    "code": 401,
                    "msg": "用户不存在"
                }
            elif status == 402:
                # 用户不是会员
                return {
                    "code": 402,
                    "msg": "用户不是会员"
                }
            elif status == 403:
                # 用户点数不够
                return {
                    "code": 403,
                    "msg": "用户点数不够"
                }
            else:
                # 其他未知错误
                return {
                    "code": status if status else 500,
                    "msg": response_data.get("msg", "未知错误")
                }
        except requests.RequestException as e:
            logging.error(f"请求外部 API 失败: {e}")
            # 外部 API 请求失败，统一返回 500
            return {
                "code": 500,
                "msg": "外部 API 请求失败"
            }
        except ValueError:
            logging.error("解析外部 API 响应失败")
            return {
                "code": 500,
                "msg": "外部 API 响应格式错误"
            }
    
    def verify_md5(self, token):
        if not token:
            return False, None
        
        # 提取 token 中的 uid 和 gskey
        try:
            token_parts = {k: v for k, v in [pair.split('=') for pair in token.split('&')]}
            uid = token_parts.get('uid')
            print("md5_uid = ",uid)
            received_md5 = token_parts.get('gskey')
            print("md5_received_md5 = ",received_md5)
        except ValueError:
            raise ValueError("Token 格式不正确，应为 'uid=<uid值>&key=<key值>'")

        if not uid or not received_md5:
            raise ValueError("Token 必须包含 'uid' 和 'key' 信息")

        # 生成原始数据并计算 MD5
        raw_data = f"{uid}{self.gskey}"  # 构造加密前的原始数据
        print("构造加密前的原始数据:",raw_data)
        # print("raw_data:",raw_data)
        calculated_md5 = hashlib.md5(raw_data.encode()).hexdigest()
        print("计算出的MD5值:", calculated_md5)
        print("接收到的MD5值:", received_md5)

        # 比较计算后的 MD5 和接收到的 MD5 是否一致
        if calculated_md5 == received_md5:
            print("MD5验证成功!")
            return True, uid   # 返回验证成功以及 UID
        else:
            print("MD5验证失败!")
            return False, None  # 验证失败返回 False 和 None
